﻿using SRB.Tg.DrawingStandard;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Teigha.Geometry;

namespace SRB.Tg.Model
{
    public static class RebarArrangement
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="Width"></param>
        /// <param name="Space"></param>
        /// <returns>返回间距列表，钢筋根数需加1</returns>
        public static List<double>  ArrangeRebar(double Width,int Space)
        {
            int num = (int)Math.Round(Width / Space, MidpointRounding.AwayFromZero);
            if (num<2)
            {
                throw new Exception();
            }
            else
            {
                double side = (Width - (num - 2) * Space) * 0.5;
                List<double> res = new List<double>();
                for (int i = 0; i < num; i++)
                {
                    if (i==0||i==num-1)
                    {
                        res.Add(side);
                    }
                    else
                    {
                        res.Add(Space);
                    }
                }
                return res;
            }
            
        }

        /// <summary>
        /// 底层和顶层钢筋布筋处理
        /// </summary>
        /// <param name="Width">总长</param>
        /// <param name="Space">间隔</param>
        /// <returns></returns>
        public static List<double> ArrangeT2BRebar(double Width, double Space)
        {
            int num =(int)((Width-(Width% Space))/Space);
            if (num < 2)
            {
                throw new Exception();
            }
            else
            {
                double side = (Width - num* Space) * 0.5;
                List<double> res = new List<double>();
                if (side > 0 && side < Space)
                {
                    side = (Width - (num-1) * Space) * 0.5;
                    if (side <= Space)
                        num = num + 1;
                    else
                    {
                        side = (Width - num * Space) * 0.5;
                        num = num + 2;
                    }
                }
                for (int i = 0; i < num; i++)
                {
                    if (i == 0 || i == num - 1)
                    {
                        if (side > 0)
                        {
                            res.Add(side);
                        }
                        else
                        {
                            res.Add(Space);
                        }
                    }
                    else
                    {
                        res.Add(Space);
                    }
                }
                return res;
            }

        }

        public static List<double> ArrangeT2BRebarAvg(double Width, double Space)
        {
            int num = (int)((Width - (Width % Space)) / Space);
            if (num < 2)
            {
                throw new Exception();
            }
            else
            {
                double side = (Width - num * Space) * 0.5;
                List<double> res = new List<double>();
                if (side > 0 && side < Space)
                {
                    //side = (Width - (num - 1) * Space) * 0.5;             
                    num = num + 2;
                }
                for (int i = 0; i < num; i++)
                {
                    if (i == 0 || i == num - 1)
                    {
                        if (side > 0)
                        {
                            res.Add(side);
                        }
                        else
                        {
                            res.Add(Space);
                        }
                    }
                    else
                    {
                        res.Add(Space);
                    }
                }
                return res;
            }

        }
        public static List<double> ArrangeT2BRebarNew(double Width, double Space)
        {
            int num = (int)((Width) / Space);
            if (num < 2)
            {
                throw new Exception();
            }
            else
            {
                double side = (Width - (num-1) * Space) * 0.5;
                List<double> res = new List<double>();
                for(int i=0;i<=num;i++)
                {
                    if (i == 0 || i == num)
                        res.Add(side);
                    else
                        res.Add(Space);
                }
                return res;
            }

        }

        /// <summary>
        /// 侧面钢筋布筋处理
        /// </summary>
        /// <param name="Width">总长</param>
        /// <param name="Space"间隔></param>
        /// <returns></returns>
        public static List<double> ArrangeSideRebar(double Width, double Space)
        {
            int num = (int)(Width / Space);
            if (num < 2)
            {
                throw new Exception();
            }
            else
            {
                double side = Width - num * Space;
                List<double> res = new List<double>();
                if (side > 0)
                    num = num + 1;
                for (int i = 0; i < num; i++)
                {
                    if (i == num - 1)
                    {
                        if (side > 0)
                        {
                            res.Add(side);
                        }
                        else
                        {
                            res.Add(Space);
                        }
                    }
                    else
                    {
                        res.Add(Space);
                    }
                }
                return res;
            }

        }

        public static void ArrangePointBySpace(Point2d st, List<double> sideLst, List<double> midleLst, double stWidth, double LineWidth, out List<Point2d> lst, out int AddNum, out int MidNum, double space = 10)
        {
            lst = new List<Point2d>();
            //double scale = LineWidth / stWidth;
            lst.Add(st.C2D());

            double len = 0;
            int num = (int)((LineWidth - sideLst.Sum()*2) / (space));
            MidNum = num;
            double avg = Math.Round((LineWidth - 2 * sideLst.Sum() - space * (num-1 )) * 0.5, 1);
            for (int i = 0; i < sideLst.Count; i++)
            {
                len += sideLst[i];
                lst.Add(st.C2D(len));
            }
            if (avg > 0)
            {
                num = num + 1;

                for (int i = 0; i < num; i++)
                {
                    if (i == 0 || i == num - 1)
                        len += avg;
                    else
                        len += space;
                    lst.Add(st.C2D(len));
                }


            }
            else
            {
                for (int i = 0; i < num; i++)
                {
                    len += space;
                    lst.Add(st.C2D(len));
                }
            }
            for (int i = 0; i < sideLst.Count; i++)
            {
                len += sideLst[sideLst.Count - 1 - i];
                lst.Add(st.C2D(len));
            }
            AddNum =(int) ((num - midleLst.Count+1)/2);
           
            double le = lst[lst.Count - 1].X - lst[0].X;
        }

        public static void ArrangePoint(Point2d st, List<double> sideLst, List<double> midleLst,double stWidth, double LineWidth,out List<Point2d> lst, int changeNum=0 )
        {
            lst = new List<Point2d>();
            double scale =  LineWidth/ stWidth ;
            lst.Add(st.C2D());
            if (changeNum == 0)
            {
                double len = 0;
                for(int i=0;i< sideLst.Count;i++)
                {
                    len += sideLst[i]* scale;
                    lst.Add(st.C2D(len));
                }
                for (int i = 0; i < midleLst.Count; i++)
                {
                    len += midleLst[i] * scale;
                    lst.Add(st.C2D(len));
                }
                for (int i = 0; i < sideLst.Count; i++)
                {
                    len += sideLst[sideLst.Count-1-i] * scale;
                    lst.Add(st.C2D(len));
                }
            }
            else
            {
                double len = 0;
                double sp = (LineWidth - stWidth) / (changeNum * 2);
                for (int i = 0; i < sideLst.Count; i++)
                {
                    len += sideLst[i];
                    lst.Add(st.C2D(len));
                }
                for(int i=0;i<changeNum;i++)
                {
                    len += sp;
                    lst.Add(st.C2D(len));
                }
                for (int i = 0; i < midleLst.Count; i++)
                {
                    len += midleLst[i] ;
                    lst.Add(st.C2D(len));
                }
                for (int i = 0; i < changeNum; i++)
                {
                    len += sp;
                    lst.Add(st.C2D(len));
                }
                for (int i = 0; i < sideLst.Count; i++)
                {
                    len += sideLst[sideLst.Count-1-i];
                    lst.Add(st.C2D(len));
                }
            }
            double le = lst[lst.Count - 1].X - lst[0].X;
        }
        public static void ArrangePointNew(Point2d st, List<double> sideLst, List<double> midleLst, double stWidth, double LineWidth, out List<Point2d> lst, double space = 12)
        {
            lst = new List<Point2d>();
            double scale =( LineWidth- sideLst.Sum()*2) / (stWidth - sideLst.Sum() * 2);
            lst.Add(st.C2D());

            double len = 0;
            int num = (int)((LineWidth - sideLst.Sum() * 2) / (space* scale));
            double avg = Math.Round((LineWidth - 2 * sideLst.Sum() - space* scale * (num - 1)) * 0.5, 1);

            for (int i = 0; i < sideLst.Count; i++)
            {
                len += sideLst[i];
                lst.Add(st.C2D(len));
            }
            if (avg > 0)
            {
                num = num + 1;
                for (int i = 0; i < num; i++)
                {
                    if (i == 0 || i == num - 1)
                        len += avg;
                    else
                        len += space * scale;
                    lst.Add(st.C2D(len));
                }
            }
            else
            {
                for (int i = 0; i < num; i++)
                {
                    len += space * scale;
                    lst.Add(st.C2D(len));
                }
            }
            for (int i = 0; i < sideLst.Count; i++)
            {
                len += sideLst[sideLst.Count - 1 - i];
                lst.Add(st.C2D(len));
            }

            double le = lst[lst.Count - 1].X - lst[0].X;
        }

        public static void ArrangeSpan(List<double> sideLst, List<double> midleLst, double stWidth, double LineWidth, out List<double> lst, int changeNum = 0)
        {
            lst = new List<double>();
            double scale = LineWidth / stWidth;
      
            if (changeNum == 0)
            {
                double len = 0;
                for (int i = 0; i < sideLst.Count; i++)
                {
                    lst.Add(sideLst[i] * scale);
                }
                for (int i = 0; i < midleLst.Count; i++)
                {
                    lst.Add(midleLst[i] * scale);
                }
                for (int i = 0; i < sideLst.Count; i++)
                {
                    lst.Add(sideLst[sideLst.Count-1-i] * scale);
                }             
            }
            else
            {
                double len = 0;
                double sp = (LineWidth - stWidth) / (changeNum * 2);
                for (int i = 0; i < sideLst.Count; i++)
                {
                    lst.Add(sideLst[i]);
                }
                for (int i = 0; i < changeNum; i++)
                {
                    lst.Add(sp);
                }
                for (int i = 0; i < midleLst.Count; i++)
                {
                    lst.Add(midleLst[i]);
                }
                for (int i = 0; i < changeNum; i++)
                {
                    lst.Add(sp);
                }
                for (int i = 0; i < sideLst.Count; i++)
                {
                    lst.Add(sideLst[sideLst.Count-1-i]);
                }
    
            }
        }

        public static void ArrangeSpanBySpace(List<double> sideLst, List<double> midleLst, double stWidth, double LineWidth, out List<double> lst, double space = 12)
        {
            lst = new List<double>();
            double scale = (LineWidth - sideLst.Sum() * 2) / (stWidth - sideLst.Sum() * 2);
            int num = (int)((LineWidth - sideLst.Sum() * 2) / (space* scale));
            double avg = Math.Round((LineWidth - 2 * sideLst.Sum() - space * scale * (num - 1)) * 0.5, 1);
            for (int i = 0; i < sideLst.Count; i++)
            {
                lst.Add(sideLst[i]);
            }
            if (avg > 0)
            {
                num = num + 1;
                for (int i = 0; i < num; i++)
                {
                    if (i == 0 || i == num - 1)
                    {
                        lst.Add(avg);
                    }
                    else
                        lst.Add(space * scale);
                }
            }
            else
            {
                for (int i = 0; i < num; i++)
                {
                    lst.Add(space * scale);
                }
            }
            for (int i = 0; i < sideLst.Count; i++)
            {
                lst.Add(sideLst[sideLst.Count - 1 - i]);
            }
            double le = lst.Sum();
        }

        public static void ArrangeSpanByMidSpace(List<double> sideLst, List<double> midleLst, int totalNum, double LineWidth, out List<double> lst,out int addChange)
        {
            lst = new List<double>();
          
            double space = (LineWidth - sideLst.Sum() * 2 - midleLst.Sum()) / (totalNum - 2 * sideLst.Count - midleLst.Count);
            int num = (totalNum - 2 * sideLst.Count - midleLst.Count) / 2;
            addChange = num;
            for (int i = 0; i < sideLst.Count; i++)
            {
                lst.Add(sideLst[i]);
            }

            for (int i = sideLst.Count; i < totalNum - sideLst.Count; i++)
            {
                if (i < sideLst.Count+num || i >= num+ sideLst.Count + midleLst.Count)
                {
                    lst.Add(space);
                }
                else
                {
                    lst.Add(midleLst[i - num - sideLst.Count]);
                }
            }

            for (int i = 0; i < sideLst.Count; i++)
            {
                lst.Add(sideLst[sideLst.Count - 1 - i]);
            }
            double le = lst.Sum();
        }
        public static void ArrangeSpace(double width, double space, out List<double> lst, out string capString)
        {
            lst = new List<double>();
            int num = (int)(width / space);
            double avg = Math.Round((width - space * (num - 1)) * 0.5, 1);
            if (avg >0)
            {
                num = num + 1;
              
            }
            capString = (num - 2) + "×" + space;

            double len = 0;
            for (int i = 0; i < num; i++)
            {
                if (i == 0 || i == num - 1)
                    lst.Add(avg);
                else
                    lst.Add(space);
            }
           
        }


        public static void ArrangeSpaceOneSide(double width, double space, out List<double> lst, out string capString, bool isEnd = true)
        {
            lst = new List<double>();
            int num = (int)(width / space);
            double Side = Math.Round(width - space * num, 1);
            num = num + 1;
            if (Side > space * 0.5)
            {
                if (isEnd)
                {
                    capString = num + "×" + space + "+" + Side;

                    double len = 0;
                    for (int i = 0; i < num; i++)
                    {
                        if (i == num - 1)
                            lst.Add(Side);
                        else
                            lst.Add(space);
                    }
                }
                else
                {
                    capString = Side + "+" + num + "×" + space;

                    double len = 0;
                    for (int i = 0; i < num; i++)
                    {
                        if (i == 0)
                            lst.Add(Side);
                        else
                            lst.Add(space);
                    }
                }
            }
            else
            {
                capString = num + "×" + space;

                double len = 0;
                for (int i = 0; i < num; i++)
                {
                    lst.Add(space);
                }
            }

        }

        public static void ArrangeBySpace(double width, double space, out List<double> lst, out string capString)
        {
            lst = new List<double>();
            int num = (int)(width / space);
            double Side = Math.Round(width - space * num, 1);

            capString = num + "×" + space;

            double len = 0;
            for (int i = 0; i < num; i++)
            {
                //if (i == 0)
                //    lst.Add(Side);
                //else
                    lst.Add(space);
            }


        }

        public static void ArrangeSpaceBothNull(double width, double space, out List<double> lst, out string capString)
        {
            lst = new List<double>();
            int num = (int)(width / space);
            double avg = Math.Round((width - space * (num - 1)) * 0.5, 1);
            if (avg > 0)
            {
                num = num + 1;

            }
            capString = (num - 2) + "×" + space;

            double len = 0;
            for (int i = 0; i < num; i++)
            {
                if (i> 0 &&i < num - 1)            
                    lst.Add(space);
            }

        }


        public static void ArrangeSpace(double width, double space,double side, out List<double> lst, out string capString)
        {
            lst = new List<double>();
            int num = (int)((width- side*2) / space);
            double avg = Math.Round((width -2* side - space * (num - 1)) * 0.5, 1);
            if (avg > 0)
            {
                num = num + 1;

            }
            capString = side + "+"+ avg +"+"+(num - 2) + "×" + space + "+" + avg + "+" + side ;

            double len = 0;
            for (int i = 0; i < num; i++)
            {
                if (i == 0 || i == num - 1)
                    lst.Add(avg);
                else
                    lst.Add(space);
            }

        }


        public static void ArrangeSpace(double width, double widthSide, double space, double side, double side2, out List<double> lst, out string capString, out string midString, out string sidString,out int sideNum)
        {
            lst = new List<double>();
            int numS = (int)((widthSide - side - side2) / space);
            if ((widthSide - side - side2) / numS >= 12 * 0.5)
                numS = numS + 1;
            sideNum = numS;
           double sideS =Math.Round((widthSide - side - side2)/numS,1);
            if(numS>1)
               sidString = numS + "×" + sideS;
            else
                sidString = sideS.ToString();
            int num = (int)((width - sideS * numS*2- side*2) / space);
            double avg = Math.Round((width - sideS * numS*2- 2 * side - space * (num - 1)) * 0.5, 1);
            if (avg > 0)
            {
                num = num + 1;
            }
            capString = side + "+" + sidString + "+" + avg + "+" + (num - 2) + "×" + space + "+" + avg + "+" + sidString + "+"+ side;
            midString =avg + "+" + (num - 2) + "×" + space + "+" + avg ;
            double len = 0;
            for (int i = 0; i < num; i++)
            {
                if (i == 0 || i == num - 1)
                {
                    if(i==0)
                    {
                        for(int m=0;m< numS;m++)
                        {
                            lst.Add(sideS);
                        }
                    }
                    lst.Add(avg);
                    if (i == num - 1)
                    {
                        for (int m = 0; m < numS; m++)
                        {
                            lst.Add(sideS);
                        }
                    }
                }
                else
                    lst.Add(space);
            }
            double lenAll = lst.Sum();
        }
    }
}
